﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Model;
using System.Net.Sockets;
using helper;
using System.IO;
using System.Xml.Serialization;
using Database;
using Common;

namespace GameHelp
{
    /// <summary>
    /// 帮助类
    /// </summary>
    public static class Manager
    {
        private static Hashtable userKeyTable = new Hashtable(15);
        private static Hashtable serverKeyTable = new Hashtable(15);
        private static Hashtable clientKeyTable = new Hashtable(15);
        private static Dictionary<Account, GameConfig> accountConfigDict = new Dictionary<Account, GameConfig>(15);
        private static Hashtable userGameStateTable = new Hashtable(15);
        private static List<Account> accountList = null;//账户集合
        private static Dictionary<int, Monster> monsterDict = new Dictionary<int, Monster>();//怪物字典
        private static object loaded = new object();
        private static bool loadSucess = false;
        /// <summary>
        /// 获取账户集合
        /// </summary>
        public static List<Account> AccountList
        {
            get { return accountList; }
        }

        /// <summary>
        /// 初始化帮助类
        /// </summary>
        public static void Init()
        {
            lock (loaded)
            {
                if (!loadSucess)
                {
					try{
						LoadAccount();
						LoadConfig();
						LoadState();
						MapDatabase.Init();
						MonsterDatabase.Init();
						EquipDatabase.Init();
						TaskDatabase.Init();

                        //MapDatabase.Save();
                        //MonsterDatabase.Save();
                        //EquipDatabase.Save();
                        //TaskDatabase.Save();

						loadSucess = true;
					}catch(Exception ex){
						Console.WriteLine("加载数据库出错，错误信息：");
						Tools.PrintException(ex);
					}
                }
            }
        }

        #region public method

        /// <summary>
        /// 根据服务器连接移除映射
        /// </summary>
        /// <param name="serverClient"></param>
        public static void RemoveByServer(TcpClient serverClient)
        {
            ConnectionMap o = serverKeyTable[serverClient] as ConnectionMap;
            if (o != null)
            {
                userKeyTable.Remove(o.Account);
                clientKeyTable.Remove(o.GameClientConnection);
                serverKeyTable.Remove(o.GameServerConnection);
            }
        }

        /// <summary>
        /// 根据客户端连接移除映射
        /// </summary>
        /// <param name="serverClient"></param>
        public static void RemoveByClient(TcpClient clientClient)
        {
            ConnectionMap o = clientKeyTable[clientClient] as ConnectionMap;
            if (o != null)
            {
                userKeyTable.Remove(o.Account);
                clientKeyTable.Remove(o.GameClientConnection);
                serverKeyTable.Remove(o.GameServerConnection);
            }
        }

        /// <summary>
        /// 根据账户移除映射
        /// </summary>
        /// <param name="serverClient"></param>
        public static void RemoveByAccount(Account account)
        {
            ConnectionMap o = userKeyTable[account] as ConnectionMap;
            if (o != null)
            {
                userKeyTable.Remove(o.Account);
                clientKeyTable.Remove(o.GameClientConnection);
                serverKeyTable.Remove(o.GameServerConnection);
            }
        }

        /// <summary>
        /// 根据角色名获取配置信息，如果还没有相应的配置信息则返回一个默认的配置
        /// </summary>
        /// <param name="characterName"></param>
        /// <returns></returns>
        public static GameConfig GetConfig(Account account)
        {
            GameConfig config = null;
            if (accountConfigDict.ContainsKey(account))
            {
                config = accountConfigDict[account];
            }
            else
            {
                config = new GameConfig();
                accountConfigDict.Add(account, config);
            }
            return config;
        }

        /// <summary>
        /// 根据账户获取游戏状态
        /// </summary>
        /// <param name="characterName"></param>
        /// <returns></returns>
        public static GameState GetState(Account account)
        {
            return userGameStateTable[account] as GameState;
        }

        /// <summary>
        /// 添加映射，以角色为键
        /// </summary>
        /// <param name="character"></param>
        /// <param name="map"></param>
        public static void AddUserKeyMap(Account account, ConnectionMap map)
        {
            userKeyTable.Add(account, map);
            if (map.GameClientConnection != null)
            {
                clientKeyTable.Add(map.GameClientConnection, map);
            }
            if (map.GameServerConnection != null)
            {
                serverKeyTable.Add(map.GameServerConnection, map);
            }
        }

        /// <summary>
        /// 添加映射，以客户端连接为键
        /// </summary>
        /// <param name="client"></param>
        /// <param name="map"></param>
        public static void AddGameClientKeyMap(TcpClient client, ConnectionMap map)
        {
            clientKeyTable.Add(client, map);

            if (map.Account != null)
            {
                if (!userKeyTable.ContainsKey(map.Account))
                {
                    userKeyTable.Add(map.Account, map);
                }
                else
                {
                    userKeyTable[map.Account] = map;
                }
            }
            if (map.GameServerConnection != null)
            {
                serverKeyTable.Add(map.GameServerConnection, map);
            }
        }

        /// <summary>
        /// 添加映射，以服务端连接为键
        /// </summary>
        /// <param name="client"></param>
        /// <param name="map"></param>
        public static void AddGameServerKeyMap(TcpClient client, ConnectionMap map)
        {
            serverKeyTable.Add(map.GameServerConnection, map);

            if (map.Account != null)
            {
                userKeyTable.Add(map.Account, map);
            }
            if (map.GameClientConnection != null)
            {
                clientKeyTable.Add(map.GameClientConnection, map);
            }
        }

        /// <summary>
        /// 根据角色获取客户端连接
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        public static TcpClient GetClientConnection(Account account)
        {
            if (userKeyTable.ContainsKey(account))
            {
                return ((ConnectionMap)userKeyTable[account]).GameClientConnection;
            }
            return null;
        }

        /// <summary>
        /// 根据账户获取服务端连接
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        public static TcpClient GetServerConnection(Account account)
        {
            if (userKeyTable.ContainsKey(account))
            {
                return ((ConnectionMap)userKeyTable[account]).GameServerConnection;
            }
            return null;
        }

        /// <summary>
        /// 根据服务端连接获取账户
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static Account GetAccountByServerConnection(TcpClient client)
        {
            if (serverKeyTable.ContainsKey(client))
            {
                return ((ConnectionMap)serverKeyTable[client]).Account;
            }
            return null;
        }

        /// <summary>
        /// 根据客户端连接获取账户
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static Characters GetCharacterByClientConnection(TcpClient client)
        {
            if (clientKeyTable.ContainsKey(client))
            {
                return ((ConnectionMap)clientKeyTable[client]).Character;
            }
            return null;
        }

        /// <summary>
        /// 根据服务端连接获取客户端连接
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static TcpClient GetClientByServerConnection(TcpClient client)
        {
            if (serverKeyTable.ContainsKey(client))
            {
                return ((ConnectionMap)serverKeyTable[client]).GameClientConnection;
            }
            return null;
        }

        /// <summary>
        /// 根据客户端连接获取服务端连接
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static TcpClient GetServerByClientConnection(TcpClient client)
        {
            if (clientKeyTable.ContainsKey(client))
            {
                return ((ConnectionMap)clientKeyTable[client]).GameServerConnection;
            }
            return null;
        }

        /// <summary>
        /// 根据客户端连接获取映射信息
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static ConnectionMap GetMapByClientConnection(TcpClient client)
        {
            if (clientKeyTable.ContainsKey(client))
            {
                return (ConnectionMap)clientKeyTable[client];
            }
            return null;
        }

        /// <summary>
        /// 根据服务端连接获取映射信息
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static ConnectionMap GetMapByServerConnection(TcpClient client)
        {
            if (serverKeyTable.ContainsKey(client))
            {
                return (ConnectionMap)serverKeyTable[client];
            }
            return null;
        }

        /// <summary>
        /// 根据账户获取映射信息
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static ConnectionMap GetMapByAccount(Account account)
        {
            if (userKeyTable.ContainsKey(account))
            {
                return (ConnectionMap)userKeyTable[account];
            }
            return null;
        }
        #endregion

        #region private method
        //加载配置信息
        static void LoadConfig()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "//config//";
            foreach (Account acc in accountList)
            {
                GameConfig config = null;
                try
                {
                    using (FileStream stream = new FileStream(path + acc.ToString("_") + "_config.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(GameConfig));
                        config = serializer.Deserialize(stream) as GameConfig;
                        stream.Close();
                    }
                }
                catch (Exception ex)
                {
                    //日志记录
                    Console.WriteLine("ConfigForm.cs 370:" + ex.Message);
                }
                if (config == null)
                {
                    config = new GameConfig();
                }

                accountConfigDict.Add(acc, config);
            }
        }

        /// <summary>
        /// 读取游戏状态
        /// </summary>
        private static void LoadState()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "//config//";

            Account[] users = new Account[accountConfigDict.Keys.Count];
            accountConfigDict.Keys.CopyTo(users, 0);

            foreach (Account o in users)
            {
                GameState state = null;

                try
                {
                    using (FileStream stream = new FileStream(path + o.ToString("_") + "_state.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(GameState));
                        state = serializer.Deserialize(stream) as GameState;
                        stream.Close();
                    }
                }
                catch (Exception ex)
                {
                    //日志记录
                    Console.WriteLine("读取角色：" + o.ToString("_") + " 的游戏状态出错，已使用默认状态文件：");
                    Tools.PrintException(ex);
                }

                if (state == null)
                {
                    state = new GameState(o.ToString("_"));
                    state.Save();
                }

                state.OnChanged += new DataChanged(state.Save);
                userGameStateTable.Add(o, state);
            }
        }

        //加载账户信息
        private static void LoadAccount()
        {
            try
            {
                using (FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "\\config\\account.xml", FileMode.Open))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(List<Account>));
                    accountList = (List<Account>)serializer.Deserialize(fs);
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                //日志记录
            }
            if (accountList == null)
            {
                accountList = new List<Account>();
            }
        }

        #endregion
    }
}
